home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / exemod.zip / EXEMOD.PAS < prev   
Pascal/Delphi Source File  |  1990-03-27  |  5KB  |  183 lines

  1. {
  2. EXEMOD.PAS - Modify global variables in EXE file
  3.  
  4. Kevin Dean
  5. 16 Kellythorne Drive
  6. DOn Mills, Ontario
  7. Canada  M3A 2L4
  8.  
  9. March 27, 1990
  10.  
  11. Modifies global variables (typed constants) in initialized data segment of EXE
  12. files.  Cannot modify global variables that are declared but not initialized
  13. (i.e. global variables that are not typed constants) as these lie in the BSS
  14. segment of the program and are not in fact in the EXE image file itself.
  15.  
  16. Copyright (c) 1990 by Kevin Dean
  17.  
  18. For Turbo Pascal versions 5.0 and above.  This code is public domain.
  19. }
  20.  
  21.  
  22. {$B-,O+,R-,I-}
  23. unit EXEMod;
  24.  
  25.  
  26. interface
  27.  
  28.  
  29. uses
  30.   DOS;
  31.  
  32.  
  33. type
  34.   EXEHeader =
  35.     record
  36.     ID : word;            { EXE file id }
  37.     ByteMod : word;        { Load module image size mod 512 }
  38.     Pages : word;        { File size (including header) div 512 }
  39.     RelocItems : word;        { Number of relocation table items }
  40.     Size : word;        { Header size in 16-byte paragraphs }
  41.     MinParagraphs : word;    { Minimum number of paragraphs above program }
  42.     MaxParagraphs : word;    { Maximum number of paragraphs above program }
  43.     StackSeg : word;        { Displacement of stack segment }
  44.     SPReg : word;        { Initial SP register value }
  45.     CheckSum : integer;        { Word checksum - negative sum (not used) }
  46.     IPReg : word;        { Initial IP register value }
  47.     CodeSeg : word;        { Displacement of code segment }
  48.     FirstReloc : word;        { First relocation item }
  49.     OvlN : word            { Overlay number }
  50.     end;
  51.  
  52. const
  53.   EXEHSize =
  54.     sizeof(EXEHeader);
  55.  
  56.   EXEID =    { EXE file signature }
  57.     $5A4D;
  58.  
  59.  
  60. function EXEModify(ProgName : PathStr; KeepDT : boolean; var Data; N : word) : integer;
  61.  
  62.  
  63. implementation
  64.  
  65.  
  66. {***}
  67. {
  68. Name        EXEModify
  69.  
  70. Function    Modifies static data in EXE files.
  71.  
  72. Declaration    EXEModify(ProgName : PathStr; KeepDT : boolean; var Data;
  73.               N : word)
  74.  
  75. Result type    integer
  76.  
  77. Remarks        EXEModify modifies global variables (typed constants) in the
  78.         initialized data segment of the current EXE file.  In DOS
  79.         versions 3.0 and up, EXEModify takes the program name from
  80.         ParamStr(0).  In DOS versions below 3.0, EXEModify searches the
  81.         DOS path for the program passed in ProgName.
  82.  
  83.         If KeepDT is true, then the original file date/time stamp is
  84.         preserved.
  85.  
  86.         EXEModify cannot modify global variables that are declared but
  87.         not initialized (i.e. global variables that are not typed
  88.         constants) as these lie in the BSS segment of the program and
  89.         are not in fact in the EXE image file itself.
  90.  
  91. Return value    EXEModify returns 1 if successful (data modified in EXE file),
  92.         0 if EXE file found but data item is not in the EXE file, and
  93.         -1 in case of file error (e.g. file not found).  If the return
  94.         value is -1, check for a file error with IOResult.
  95. }
  96. function EXEModify(ProgName : PathStr; KeepDT : boolean; var Data; N : word) : integer;
  97.  
  98. var
  99.   _ProgName : PathStr;    { Program name }
  100.   RetCode : integer;    { Function return code }
  101.   OldFileMode : byte;    { Old file open mode }
  102.   ProgFile : file;    { Program file handle }
  103.   EXE : EXEHeader;    { EXE file header }
  104.   NumRW : word;        { Number of bytes read or written }
  105.   FileLen : longint;    { Program file length }
  106.   DTStamp : longint;    { Program date/time stamp }
  107.   SeekLen : longint;    { Seek length into program file }
  108.  
  109. begin
  110. if Lo(DOSVersion) < 3 then
  111.   { Search path for program }
  112.   begin
  113.   _ProgName := FSearch(ProgName, GetEnv('PATH'));
  114.   if _ProgName <> '' then
  115.     _ProgName := FExpand(_ProgName);
  116.   end
  117. else
  118.   { Program name is 0th parameter in DOS versions 3.0 and up }
  119.   _ProgName := ParamStr(0);
  120.  
  121. { Assume error }
  122. RetCode := -1;
  123.  
  124. if _ProgName <> '' then
  125.   begin
  126.   { Set file mode to allow reading and writing }
  127.   OldFileMode := FileMode;
  128.   FileMode := 2;
  129.  
  130.   Assign(ProgFile, _ProgName);
  131.   Reset(ProgFile, 1);
  132.  
  133.   FileMode := OldFileMode;
  134.  
  135.   if InOutRes = 0 then
  136.     begin
  137.     BlockRead(ProgFile, EXE, EXEHSize, NumRW);
  138.  
  139.     if (NumRW <> EXEHSize) or (EXE.ID <> EXEID) then
  140.       { File does not have valid EXE file header so say file not found }
  141.       InOutRes := 2
  142.     else
  143.       begin
  144.       { Cannot write beyond end of file }
  145.       FileLen := FileSize(ProgFile);
  146.  
  147.       if KeepDT then
  148.     { Save date/time stamp }
  149.     GetFTime(ProgFile, DTStamp);
  150.  
  151.       RetCode := 0;
  152.  
  153.       SeekLen := LongInt(Seg(Data) - (PrefixSeg + 16) + EXE.Size) shl 4 + LongInt(Ofs(Data));
  154.  
  155.       if SeekLen + N <= FileLen then
  156.     begin
  157.     Seek(ProgFile, SeekLen);
  158.     if InOutRes = 0 then
  159.       begin
  160.       BlockWrite(ProgFile, Data, N, NumRW);
  161.       if (InOutRes = 0) and (NumRW = N) then
  162.         { Seek and write was successful }
  163.         RetCode := 1
  164.       end
  165.     end;
  166.  
  167.       if KeepDT then
  168.     { Restore date/time stamp }
  169.     SetFTime(ProgFile, DTStamp)
  170.       end;
  171.  
  172.     Close(ProgFile)
  173.     end
  174.   end
  175. else
  176.   { File not found }
  177.   InOutRes := 2;
  178.  
  179. EXEModify := RetCode
  180. end;
  181.  
  182.  
  183. end.